﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace DARE
{
    public class CTimeConfig
    {

    #region fields

        private CDare m_dare;
        private GameTime m_gameTime;

        private float m_timeSpeed;

        private bool m_updateTimeStep;
        private bool m_updateTimeSinceLastFrame;

        private float m_timeStep;
        private float m_timeSinceLastFrame;

        private bool m_updateFixedTimeStep;
        private bool m_updateFixedTimeSinceLastFrame;

        private float m_fixedTimeStep;
        private float m_fixedTimeSinceLastFrame;

        private bool m_isPaused;
        private float m_saveTimeSpeed;

    #endregion

    #region properties

        public CDare Dare
        {
            get { return m_dare; }
        }

        public GameTime GameTime
        {
            get { return m_gameTime; }
        }

        public float TimeSpeed
        {
            get { return m_timeSpeed; }
            set { m_timeSpeed = m_saveTimeSpeed = value < 0.0f ? 0.0f : value; }
        }

        public float TimeStep
        {
            get
            {
                if (m_updateTimeStep)
                {
                    m_timeStep = (float)m_gameTime.ElapsedGameTime.Ticks / (float)TimeSpan.TicksPerSecond * m_timeSpeed;
                    m_updateTimeStep = false;
                }
                return m_timeStep;
            }
        }

        public float TimeSinceLastFrame
        {
            get
            {
                if (m_updateTimeSinceLastFrame)
                {
                    m_timeSinceLastFrame = (float)m_gameTime.ElapsedGameTime.TotalMilliseconds * m_timeSpeed;
                    m_updateTimeSinceLastFrame = false;
                }
                return m_timeSinceLastFrame;
            }
        }

        public float FixedTimeStep
        {
            get
            {
                if (m_updateFixedTimeStep)
                {
                    m_fixedTimeStep = (float)(m_gameTime.ElapsedGameTime.Ticks / TimeSpan.TicksPerSecond);
                    m_updateFixedTimeStep = false;
                }
                return m_fixedTimeStep;
            }
        }

        public float FixedTimeSinceLastFrame
        {
            get
            {
                if (m_updateFixedTimeSinceLastFrame)
                {
                    m_fixedTimeSinceLastFrame = (float)m_gameTime.ElapsedGameTime.TotalMilliseconds;
                    m_updateFixedTimeSinceLastFrame = false;
                }
                return m_fixedTimeSinceLastFrame;
            }
        }

        public bool IsPaused
        {
            get { return m_isPaused; }
            set
            {
                if (value == true)
                {
                    m_timeSpeed = 0;
                    m_isPaused = true;
                }
                else if (value == false)
                {
                    m_timeSpeed = m_saveTimeSpeed;
                    m_isPaused = false;
                }
            }
        }

    #endregion

    #region ctor

        public CTimeConfig()
        {
            Initialize(CDare.Instance);
        }

        public CTimeConfig(CDare dare)
        {
            Initialize(dare);
        }

        private void Initialize(CDare dare)
        {
            m_dare = dare;
            m_timeSpeed = m_saveTimeSpeed = 1.0f;
            m_isPaused = false;
            m_updateTimeStep = false;
            m_updateTimeSinceLastFrame = false;
            m_timeStep = 0.0f;
            m_timeSinceLastFrame = 0.0f;
            m_gameTime = new GameTime();
        }

    #endregion

    #region methods

        internal void Update(GameTime gameTime)
        {
            m_gameTime = gameTime;
            m_updateTimeStep = true;
            m_updateTimeSinceLastFrame = true;
            m_updateFixedTimeStep = true;
            m_updateFixedTimeSinceLastFrame = true;
        }

    #endregion

    }
}
